package ai.people.platform.system.service.impl;

import ai.people.netmon.framework.domain.system.entity.NmSystemMenu;
import ai.people.netmon.framework.domain.system.entity.NmSystemRoleMenu;
import ai.people.netmon.framework.exception.enums.CommonEnum;
import ai.people.netmon.framework.exception.enums.SystemExceptionEnum;
import ai.people.netmon.framework.utils.AssertUtils;
import ai.people.platform.system.mapper.NmSysRoleMenuMapper;
import ai.people.platform.system.service.SysRoleMenuService;
import ai.people.platform.system.service.SystemMenuService;
import ai.people.platform.system.service.SystemRoleService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色权限菜单 服务实现类
 * </p>
 *
 * @author zhenglin
 * @since 2022-03-22
 */
@Service
@RequiredArgsConstructor
public class SysRoleMenuServiceImpl extends ServiceImpl<NmSysRoleMenuMapper, NmSystemRoleMenu> implements SysRoleMenuService {


    /**
     * 系统角色服务
     */
    private final SystemRoleService systemRoleService;

    /**
     * 系统菜单服务
     */
    private final SystemMenuService systemMenuService;

    /**
     * 保存角色菜单
     *
     * @param roleId  角色id
     * @param menuIds 菜单id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveRoleMenu(Long roleId, List<Long> menuIds) {
        systemRoleService.checkRoleExists(roleId);
        menuIds = menuIds.stream().distinct().collect(Collectors.toList());
        List<NmSystemMenu> nmSystemMenus = systemMenuService.listMenuInIds(menuIds);
        Set<Long> dbMenuIds = nmSystemMenus.stream().map(NmSystemMenu::getId).collect(Collectors.toSet());
        // 无效的id
        String invalidId = menuIds.stream().filter(aLong -> !dbMenuIds.contains(aLong)).map(String::valueOf).collect(Collectors.joining(","));
        // 存在无效的id 返回错误信息
        AssertUtils.isTrue(invalidId.isBlank(), SystemExceptionEnum.INVALID_MENU_ID.getCode(), SystemExceptionEnum.INVALID_MENU_ID.getMessage() + "[" + invalidId + "]");
        List<NmSystemRoleMenu> roleMenuList = menuIds.stream().map(menuId -> new NmSystemRoleMenu(null, roleId, menuId)).collect(Collectors.toList());
        LambdaQueryWrapper<NmSystemRoleMenu> lambdaQuery = Wrappers.lambdaQuery(NmSystemRoleMenu.class);
        lambdaQuery.eq(NmSystemRoleMenu::getRoleId, roleId);
        this.remove(lambdaQuery);
        boolean saveResult = this.saveBatch(roleMenuList);
        AssertUtils.isTrue(saveResult, CommonEnum.FAIL);
    }

    /**
     * 通过角色id删除角色菜单
     *
     * @param roleId 角色id
     */
    @Override
    public void deleteRoleMenuByRoleId(Long roleId) {
        LambdaQueryWrapper<NmSystemRoleMenu> lambdaQuery = Wrappers.lambdaQuery(NmSystemRoleMenu.class);
        lambdaQuery.eq(NmSystemRoleMenu::getRoleId, roleId);
        boolean removeResult = this.remove(lambdaQuery);
        AssertUtils.isTrue(removeResult, SystemExceptionEnum.CHARACTER_MENU_DELETION_FAILED);
    }

    /**
     * 通过菜单id删除角色菜单
     *
     * @param menuId 菜单id
     */
    @Override
    public void deleteRoleMenuByMenuId(Long menuId) {
        LambdaQueryWrapper<NmSystemRoleMenu> lambdaQuery = Wrappers.lambdaQuery(NmSystemRoleMenu.class);
        lambdaQuery.eq(NmSystemRoleMenu::getMenuId, menuId);
        List<NmSystemRoleMenu> roleMenuList = this.list(lambdaQuery);
        if (roleMenuList.isEmpty()) {
            return;
        }
        boolean removeResult = this.remove(lambdaQuery);
        AssertUtils.isTrue(removeResult, SystemExceptionEnum.MENU_PERMISSION_DELETION_FAILED);
    }


}
